package com.fast.fast.common.gateway.controller;

import cn.hutool.captcha.CaptchaUtil;
import cn.hutool.captcha.LineCaptcha;
import cn.hutool.core.util.ObjectUtil;
import com.fast.fast.common.base.constant.CacheConstants;
import com.fast.fast.common.base.vo.Result;
import com.fast.fast.common.gateway.entity.SysUser;
import com.fast.fast.common.gateway.service.LoginService;
import com.fast.fast.common.redis.util.RedisUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.core.io.buffer.DataBufferFactory;
import org.springframework.http.MediaType;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.util.FastByteArrayOutputStream;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.util.Map;

/**
 * 登录Controller
 *
 * @author lyf
 * @date 2022/01/01 00:00 周六
 **/
@Slf4j
@RequiredArgsConstructor
@RestController
public class LoginController {

    private final LoginService loginService;

    private final RedisUtils redisUtils;

    @GetMapping("getCaptcha")
    public Mono<Void> getCaptcha(ServerWebExchange exchange) {
        ServerHttpRequest request = exchange.getRequest();
        ServerHttpResponse response = exchange.getResponse();

        // 获取入参
        String uuid = (request.getQueryParams().getFirst("uuid"));
        if (ObjectUtil.isEmpty(uuid)) {
            log.debug("验证码uuid不能为空");
            return null;
        }
        // 定义图形验证码的长、宽、验证码字符数、干扰线宽度
        LineCaptcha captcha = CaptchaUtil.createLineCaptcha(120, 60, 4, 2);
        // 验证码字符串
        String code = captcha.getCode();
        // 缓存验证码字符串到redis
        redisUtils.set(CacheConstants.GATEWAY_LOGIN_VERIFY_CODE_PREFIX + uuid, code, 120);
        // 写入流
        FastByteArrayOutputStream outputStream = new FastByteArrayOutputStream();
        captcha.write(outputStream);

        // body
        Flux<DataBuffer> flux = Flux.create(sink -> {
            DataBufferFactory dataBufferFactory = response.bufferFactory();
            DataBuffer dataBuffer = dataBufferFactory.wrap(outputStream.toByteArray());
            sink.next(dataBuffer);
            sink.complete();
        });
        response.getHeaders().setContentType(MediaType.IMAGE_JPEG);
        return response.writeWith(flux);

    }

    /**
     * 登录，会在浏览器cookie中添加satoken
     *
     * @param sysUser
     * @return
     */
    @PostMapping("login")
    public Result<Map<String, Object>> login(SysUser sysUser) {
        return loginService.login(sysUser);
    }

    /**
     * 退出，会删除浏览器cookie中的satoken，同时删除redis中对应的key
     *
     * @return
     */
    @GetMapping("logout")
    public Result<?> logout() {
        return loginService.logout();
    }

    /**
     * 获取redis中登录用户的权限和角色信息
     *
     * @return
     */
    @GetMapping("getPermAndRole")
    public Result<?> getPermAndRole() {
        return loginService.getPermAndRole();
    }

    /**
     * 前端通过ajax轮询，监听登录用户的权限和角色是否发生变化，若发生变化将自动刷新页面
     *
     * @return
     */
    @GetMapping("refreshPermAndRole")
    public Result<?> refreshPermAndRole() {
        return loginService.refreshPermAndRole();
    }

    /**
     * 获取当前在线用户集合
     *
     * @return
     */
    @PostMapping("listOnlineUsers")
    public Result<?> listOnlineUsers(SysUser po) {
        return loginService.listOnlineUsers(po);
    }

}
